#include "DynamicLinkedSlave.hpp"
//#include "../../tAutomaLibCpp/tAutomaLibCppVars.hpp"
#include "PGMFC/JSONWrapperPGMFC.hpp"
#include "MiscUtils/TdrMisc/SEngine.h"

// https://github.com/nbsdx/SimpleJSON

using namespace std;

int DynamicLinkedSlave::init(GeneralSlave* ref) {
	_meta = ref->_meta;
	_comm = ref->_comm;

	_comm._conStat = ConnectionStatus::Missing;
	_generalStat._exeStat = ExecutionStatus::NotAvailable;
	return 1;
}

using namespace std;

int DynamicSlaveCalls::loadDriver(std::wstring platform, int simuSpeed) {
	if (platform.compare(L"pgmfc") == 0) {
		return JsonWrapperPGMFC::loadLibrary((simuSpeed > 0) ? 1 : 0);
	}
	return -1;
}

int DynamicSlaveCalls::getSlaveInfo(std::wstring platform, std::wstring model,
	std::wstring& type,
	std::wstring& subType,
	std::wstring& connectionType,
	std::wstring& connectionSubType) {
	if (platform.compare(L"pgmfc") == 0) {
		type = L"Pressure pump";
		subType = L"Pressure pump";
		connectionType = L"usb";
		connectionSubType = L"OEM driver";
		return 1;
	}
	return 0;
}

void* DynamicSlaveCalls::connectSlave(std::wstring platform, std::wstring model, int* errCode, std::wstring* errMsg) {
	if (platform.compare(L"pgmfc") == 0) {
		void* ret = JsonWrapperPGMFC::connect();
		if (ret == nullptr) {
			*errCode = -2;
			*errMsg = L"No detail";
		}
		else {
			*errCode = 0;
			*errMsg = L"";
		}
		return ret;
	}
	return nullptr;
}

int DynamicSlaveCalls::getSlaveDescriptor(std::wstring platform, void* nativeHandle,
	JSONObject* dataOut,
	JSONObject* errorOut) {
	if (platform.compare(L"pgmfc") == 0) {
		return getMFCSPressurePumpDescriptor(nativeHandle, dataOut, errorOut);
	}
	return 0;
}

int DynamicSlaveCalls::callFunction(std::wstring platform, void* nativeHandle,
	const wchar_t* functionName,
	JSONObject* parasIn,
	JSONObject* dataOut,
	JSONObject* errorOut,
	std::wstring logFilename) {

	if (platform.compare(L"pgmfc") == 0) {
		return JsonWrapperPGMFC::callFunction(nativeHandle, functionName, parasIn,
			dataOut, errorOut, logFilename);
	}

	return 0;
}

// serial_number
// channel_count
// module_id
// firmware_version
int DynamicSlaveCalls::getMFCSPressurePumpDescriptor(void* nativeHandle, JSONObject* dataOut, JSONObject* errorWithTypeOut, int isSimulated) {
	string sn = "NA", fmVer = "NA";
	int channelCount = -1, moduleId = 0;
	if (isSimulated > 0) {
		sn = "Simu";
		fmVer = "Umis";
		channelCount = 2;
		moduleId = 3;
	}
	else {
		int allGood = true;
		if (allGood) {
			allGood = JsonWrapperPGMFC::getSerialNo(nativeHandle, sn, errorWithTypeOut);
		}
		else {
			JsonWrapperPGMFC::getSerialNo(nativeHandle, sn, nullptr);
		}
		if (allGood) {
			allGood = JsonWrapperPGMFC::getChannelCount(nativeHandle, channelCount, errorWithTypeOut);
		}
		else {
			JsonWrapperPGMFC::getChannelCount(nativeHandle, channelCount, nullptr);
		}
		if (allGood) {
			allGood = JsonWrapperPGMFC::getModuleID(nativeHandle, moduleId, errorWithTypeOut);
		}
		else {
			JsonWrapperPGMFC::getModuleID(nativeHandle, moduleId, nullptr);
		}
		if (allGood) {
			allGood = JsonWrapperPGMFC::getFirmwareVersion(nativeHandle, fmVer, errorWithTypeOut);
		}
		else {
			JsonWrapperPGMFC::getFirmwareVersion(nativeHandle, fmVer, nullptr);
		}
	}

	wstring snW, fmVerW;
	for (char snC : sn) {
		snW.push_back(snC);
	}
	for (char fmVerC : fmVer) {
		fmVerW.push_back(fmVerC);
	}
	(*dataOut)[L"serial_number"] = new JSONValue(snW);
	(*dataOut)[L"channel_count"] = new JSONValue(channelCount);
	(*dataOut)[L"module_id"] = new JSONValue(moduleId);
	(*dataOut)[L"firmware_version"] = new JSONValue(fmVerW);

	return 1;
}